#include<iostream>
#include<string>
#include<memory>

class Computer
{
public:
    Computer(){}
    void setBoard(const std::string &board)
    {_board = board;}
    void setDisplay(const std::string &display)
    {_display = display;}

    void showParamaters()
    {
        std::string param = "Computer Paramaters：\n";
        param += "\tBoard: " + _board + "\n";
        param += "\tDisplay: " + _display + "\n";
        param += "\tOS: " + _os + "\n";
        std::cout<<param<<std::endl;
    }
    virtual void setOs() = 0;
protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

class MacBook:public Computer
{
public:
    void setOs() override
    {
        _os ="Mac OS X12";
    }
};

class Builder
{
public:
    virtual void BuildBoard(const std::string &board) = 0;
    virtual void BuildDisplay(const std::string &display) = 0;
    virtual void BuildOS() = 0;
    virtual std::shared_ptr<Computer> build() = 0;
};

class MacBookBuilder:public Builder
{
public:
    MacBookBuilder()
    :_computer(new MacBook())
    {}
    void BuildBoard(const std::string &board)
    {
        _computer->setBoard(board);
    }
    void BuildDisplay(const std::string &display)
    {
        _computer->setDisplay(display);
    }
    void BuildOS()
    {
        _computer->setOs();
    }
    std::shared_ptr<Computer> build()
    {
        return _computer;
    }
private:
    std::shared_ptr<Computer> _computer;
};

class Director
{
public:
    Director(Builder *builder)
    :_builder(builder)
    {}
    void construct(const std::string &board,const std::string &display)
    {
        _builder->BuildBoard(board);
        _builder->BuildDisplay(display);
        _builder->BuildOS();
    }
private:
    std::shared_ptr<Builder> _builder;
};

int main()
{
    Builder *builder = new MacBookBuilder();
    std::unique_ptr<Director> director(new Director(builder));
    director->construct("华硕主板","三星显示器"); 
    std::shared_ptr<Computer> computer = builder->build();
    computer->showParamaters();
    return 0;
}